package tech.yingchuan.blogs.service.impl;

import com.google.common.base.Preconditions;
import com.google.common.collect.Maps;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import tech.yingchuan.blogs.common.BeanValidator;
import tech.yingchuan.blogs.common.BizCodeType;
import tech.yingchuan.blogs.dto.AclDto;
import tech.yingchuan.blogs.exception.ParamException;
import tech.yingchuan.blogs.mapper.AclMapper;
import tech.yingchuan.blogs.model.Acl;
import tech.yingchuan.blogs.param.AclParam;
import tech.yingchuan.blogs.service.AclService;
import tech.yingchuan.blogs.service.common.CheckService;

import java.util.Date;
import java.util.List;
import java.util.Map;

@Service
public class AclServiceImpl implements AclService,CheckService {

    @Autowired
    private AclMapper aclMapper;
    @Autowired
    private SequenceService sequence;

    /**
     * 保存一条权限信息
     *
     * @param aclParam
     */
    @Override
    public void saveAcl(AclParam aclParam) {
        BeanValidator.check(aclParam);
        if (checkExist(cheackSaveParamMap(aclParam))){
            throw new ParamException("当前权限模块下面存在相同名称的权限点");
        }
        Acl acl=Acl.builder().aclName(aclParam.getAclName()).aclCode(aclParam.getAclCode()).url(aclParam.getUrl())
                .seq(aclParam.getSeq()).isStatus(aclParam.getIsStatus()).type(aclParam.getType())
                .aclParentId(aclParam.getAclParentId()).remark(aclParam.getRemark()).build();
        acl.setAclId(sequence.generate(BizCodeType.TYPE_USERID));
        acl.setOperator("ADMIN");//TODO:
        acl.setOperateIp("0:0:0:0");//TODO:
        acl.setOperateTime(new Date());
        aclMapper.insertSelective(acl);
    }

    /**
     * 更新一条权限信息
     *
     * @param aclParam
     */
    @Override
    public void updateAcl(AclParam aclParam) {
        if (checkExist(cheackUpdateParamMap(aclParam))) {
            throw new ParamException("当前权限模块下面存在相同名称的权限点");
        }
        Acl before=aclMapper.selectByPrimaryKey(aclParam.getAclId());
        Preconditions.checkNotNull(before, "待更新的权限点不存在");
        Acl acl=Acl.builder().aclId(aclParam.getAclId()).aclName(aclParam.getAclName())
                .aclCode(aclParam.getAclCode()).url(aclParam.getUrl())
                .seq(aclParam.getSeq()).isStatus(aclParam.getIsStatus())
                .type(aclParam.getType()).aclParentId(aclParam.getAclParentId())
                .remark(aclParam.getRemark()).build();
        acl.setOperator("ADMIN");
        acl.setOperateIp("0:0:0:0");
        acl.setOperateTime(new Date());
        aclMapper.updateByPrimaryKeySelective(acl);
    }

    /**
     * 根据权限id删除一条数据
     *
     * @param aclId
     */
    @Override
    public void removeIdAcl(String aclId) {
        aclMapper.deleteByPrimaryKey(aclId);
        List<Acl> acls = aclMapper.selectByAclParentId(aclId);
        acls.stream().map(a->a.getAclId()).forEach(this::removeIdAcl);
    }

    /**
     * 批量删除权限信息
     *
     * @param aclIds
     */
    @Override
    public void removeBatchIdAcl(List<String> aclIds) {
        aclIds.stream().forEach(this::removeIdAcl);
    }

    /**
     * 根据权限id
     * 获取权限信息
     *
     * @param aclId
     * @return
     */
    @Override
    public AclDto getAcl(String aclId) {
        Acl acl=aclMapper.selectByPrimaryKey(aclId);
        return AclDto.adapt(acl);
    }

    /**
     * 查询权限列表（分页）
     *
     * @param aclParam
     * @return
     */
    @Override
    public List<Acl> listAcl(AclParam aclParam) {
        return aclMapper.selectAll();
    }

    /**
     * 上级菜单列表
     *
     * @return
     */
    @Override
    public List<Acl> listAclParentTree() {
        List<Acl> acls = aclMapper.selectAll();
        return acls;
    }

    @Override
    public boolean checkExist(Map<String,Object> map){
        if (map.get("aclParentId")==null){
            return aclMapper.countSaveByNameAndParentId(map)>0;
        }else {
            return aclMapper.countUpdateByNameAndParentId(map)>0;
        }

    }

    /**
     *  权限名查重校验
     *  所需的参数准备
     * @param aclParam
     * @return
     */
    public Map<String,Object> cheackSaveParamMap(AclParam aclParam){
        Map<String,Object> param= Maps.newHashMap();
        param.put("aclName",aclParam.getAclName());
        param.put("aclId",aclParam.getAclId());
        return param;
    }

    /**
     *  权限名查重校验
     *  所需的参数准备
     * @param aclParam
     * @return
     */
    public Map<String,Object> cheackUpdateParamMap(AclParam aclParam){
        Map<String,Object> param= Maps.newHashMap();
        param.put("aclName",aclParam.getAclName());
        param.put("aclParentId",aclParam.getAclParentId());
        param.put("aclId",aclParam.getAclId());
        return param;
    }
}
